import { ProjectResources, Resource } from "@/interface/entity";
import store from "@/store";
import { constObjs } from "@/const/const";
import Request from "@/api/request";
import { ElMessage } from "element-plus";

// add file to a project
export async function addFileToProject(
  projectGuid: string,
  res: object,
  fileType: string,
  chunk: number,
  tmpGuid: string
  // requestCallback: (arg0: ProgressEvent) => void
) {
  const file = res["raw" as keyof object] as File;
  const formData = new FormData();
  // 分片大小
  const chunkSize = 1024 * 1024 * 5,
    maxSize = 1024 * 1024 * 200,
    maxChunk = Math.ceil(file.size / chunkSize);

  if (file.size > maxSize) {
    ElMessage.error("文件大小不能超过200MB");
    return;
  }

  if (file.size == 0 || file.size == undefined) {
    ElMessage.error("请勿上传空文件");
    return;
  }

  (res["percentage" as keyof object] as number) = parseFloat(
    ((chunk * 100) / maxChunk).toFixed(2)
  );

  formData.append(
    "file",
    file.slice(chunk * chunkSize, (chunk + 1) * chunkSize)
  );
  formData.append("name", file.name);
  formData.append("chunk", chunk.toString());
  formData.append("maxChunk", maxChunk.toString());
  formData.append("guid", tmpGuid);

  await Request({
    method: "post",
    url: "ProjectResource/updateProjectResources",
    headers: { "Content-Type": "multipart/form-data" },
    // data can be used with params
    data: formData,
    params: {
      projectGuid: projectGuid,
      fileType: fileType
    }
  }).then(async response => {
    if (response.data != true) {
      // 递归上传下一个分片
      await addFileToProject(projectGuid, res, fileType, ++chunk, tmpGuid);
    }
  });
  return;
}
// get fileNames of a type
export async function queryFileNamesByType(
  projectGuid: string,
  fileType: string
) {
  await Request({
    method: "get",
    url: "ProjectResource/queryFileNamesByType",
    params: {
      projectGuid: projectGuid,
      fileType: fileType
    }
  }).then(response => {
    store.state.fileNameList = response.data as string[];
    console.log(store.state.fileNameList);
  });
}

export async function queryProjectResource(
  projectGuid: string,
  fileType: string,
  fileName: string,
  toPDF: boolean,
  resource: Resource
) {
  await Request({
    method: "get",
    url: "ProjectResource/queryProjectResource",
    // responseType: "arraybuffer",
    responseType: "blob",
    timeout: 10000000,
    timeoutErrorMessage: "不好意思，文件太大了，请重试",
    params: {
      projectGuid: projectGuid,
      fileType: fileType,
      fileName: fileName,
      toPDF: toPDF
    }
  })
    .then(response => {
      resource.url = new Blob([response.data], { type: response.data.type });
    })
    .catch(error => {
      console.log(error.response.status, error.response.data, "该资源不存在");
    });
}

export async function deleteProjectResource(
  projectGuid: string,
  fileType: string,
  fileName: string
) {
  await Request({
    method: "delete",
    url: "ProjectResource/deleteProjectResource",
    params: {
      projectGuid: projectGuid,
      fileType: fileType,
      fileName: fileName
    }
  });
}

// get files of a type by type
export async function queryProjectResourceByType(
  projectGuid: string,
  fileType: string
) {
  // init state(not delete the guid)
  store.state.projectResources.resources = (JSON.parse(
    JSON.stringify(constObjs.projectResources)
  ) as ProjectResources).resources;

  // await
  await queryFileNamesByType(projectGuid, fileType);

  // query resource by name (ordered by name)
  await Promise.all(
    store.state.fileNameList.map(async name => {
      const resource = {} as Resource;
      resource.name = name;
      await queryProjectResource(projectGuid, fileType, name, false, resource);
      // get upload time
      await Request({
        method: "get",
        url: "ProjectResource/queryProjectResourceUploadTime",
        params: {
          projectGuid: projectGuid,
          fileType: fileType,
          fileName: name
        }
      }).then(response => {
        resource.createdDate = response.data as string;
      });

      store.state.projectResources.resources
        .find(resource => resource.fileType == fileType)
        ?.resource.push(resource);
    })
  );
}

// query
export async function queryProjectResourceList(projectGuid: string) {
  // query resource from db
  await Promise.all(
    constObjs.fileTypeList.map(async type => {
      await queryProjectResourceByType(projectGuid, type);
    })
  );
}
